package com.weishaoying.practice.web;

import com.weishaoying.practice.exception.CustomException;
import com.weishaoying.practice.util.PasswordUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

/**
 * @author WeiShaoying
 * @date 2017/12/27
 */
@Controller
public class LoginAction {

    private String PREFIX = "--------LoginAction----";

    @RequestMapping("/login")
    public String login(String username, String password, Model model) {
        Subject subject = SecurityUtils.getSubject();
        if (!subject.isAuthenticated()) {
            //没有凭证管理器的时候
            String salt = "AK88";//TODO:根据username到数据库中查询盐值
            String credentials = PasswordUtil.generateCredent(password, salt);
            UsernamePasswordToken token = new UsernamePasswordToken(username, credentials);

            //UsernamePasswordToken token = new UsernamePasswordToken(username, password);
            //token.setRememberMe(subject.isRemembered());
            token.setRememberMe(true);
            System.out.println(PREFIX + "token = " + token);
            try {
                //执行登录，会调用Realm的方法
                subject.login(token);
            } catch (UnknownAccountException ex) {
                model.addAttribute("msg", "用户名不存在");
                System.out.println(PREFIX + "用户名不存在" + ex);
                //ex.printStackTrace();
            } catch (IncorrectCredentialsException ex) {
                model.addAttribute("msg", "密码错误");
                System.out.println(PREFIX + "密码错误" + ex);
            } catch (AuthenticationException e) {//其他的登录错误
                model.addAttribute("msg", "登录验证失败");
                System.out.println(PREFIX + "登录验证失败=" + e);
            }
        }
        if (subject.isAuthenticated()) {
            model.addAttribute("username", username);
            return "home";
        }
        return "error";
    }


    //登陆提交地址，和applicationContext-shiro.xml中配置的loginurl一致
    @RequestMapping("/login222")
    public String login(HttpServletRequest request) throws Exception {
        System.out.println(PREFIX + "request.getRequestURI() = " + request.getRequestURI());
        //如果登陆失败从request中获取认证异常信息，shiroLoginFailure就是shiro异常类的全限定名
        String exceptionClassName = (String) request.getAttribute("shiroLoginFailure");
        System.out.println(PREFIX + "exceptionClassName = " + exceptionClassName);

        //根据shiro返回的异常类路径判断，抛出指定异常信息
        if (exceptionClassName != null) {
            if (UnknownAccountException.class.getName().equals(exceptionClassName)) {
                //最终会抛给异常处理器
                throw new CustomException("账号不存在");
            } else if (IncorrectCredentialsException.class.getName().equals(
                    exceptionClassName)) {
                throw new CustomException("用户名/密码错误");
            } else if ("randomCodeError".equals(exceptionClassName)) {
                throw new CustomException("验证码错误 ");
            } else {
                throw new Exception();//最终在异常处理器生成未知错误
            }
        }
        //此方法不处理登陆成功（认证成功），shiro认证成功会自动跳转到上一个请求路径
        //登陆失败还到login页面
        return "login";
    }


    //用户退出
    @RequestMapping("/logout")
    @ResponseBody
    public String logout(HttpSession session) throws Exception {
        session.invalidate();
        return "logout success";
    }
}
